package com.openmanus.agent.core;

import com.openmanus.agent.memory.Memory;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;

import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 智能体基类
 * 定义了智能体的基本属性和行为
 * 
 * @author OpenManus Team
 * @version 1.0.0
 */
@Slf4j
@Getter
@Setter
public abstract class BaseAgent {

    @Autowired
    private ApplicationEventPublisher eventPublisher;

    // 智能体基本属性
    private final String name;
    private final String description;
    private AgentState state = AgentState.IDLE;
    private final AtomicInteger currentStep = new AtomicInteger(0);

    // 配置参数
    private int maxSteps = 10;
    private Duration timeout = Duration.ofMinutes(5);

    // 依赖组件
    private Memory memory;

    protected BaseAgent(String name, String description) {
        this.name = name;
        this.description = description;
    }

    /**
     * 异步执行智能体任务
     * 
     * @param request 用户请求
     * @return 智能体执行结果
     */
    public CompletableFuture<AgentResult> runAsync(String request) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                log.info("Agent [{}] starting execution for request: {}", name, request);
                setState(AgentState.RUNNING);
                
                AgentContext context = createContext(request);
                return executeSteps(context);
                
            } catch (Exception e) {
                log.error("Agent [{}] execution failed", name, e);
                setState(AgentState.ERROR);
                return AgentResult.error("Agent execution failed: " + e.getMessage());
            } finally {
                setState(AgentState.IDLE);
                currentStep.set(0);
            }
        });
    }

    /**
     * 执行多步骤任务
     * 
     * @param context 智能体上下文
     * @return 执行结果
     */
    private AgentResult executeSteps(AgentContext context) {
        while (currentStep.get() < maxSteps && !context.isCompleted()) {
            try {
                int step = currentStep.incrementAndGet();
                log.debug("Agent [{}] executing step {}/{}", name, step, maxSteps);
                
                StepResult stepResult = executeStep(context).join();
                context.addStepResult(stepResult);
                
                if (stepResult.isTerminal()) {
                    log.info("Agent [{}] completed execution at step {}", name, step);
                    return AgentResult.success(stepResult.getOutput());
                }
                
            } catch (Exception e) {
                log.error("Agent [{}] step {} failed", name, currentStep.get(), e);
                return AgentResult.error("Step execution failed: " + e.getMessage());
            }
        }
        
        if (currentStep.get() >= maxSteps) {
            log.warn("Agent [{}] reached maximum steps limit", name);
            return AgentResult.error("Maximum steps limit reached");
        }
        
        return AgentResult.success(context.getFinalOutput());
    }

    /**
     * 执行单步操作（抽象方法，由子类实现）
     * 
     * @param context 智能体上下文
     * @return 步骤执行结果
     */
    protected abstract CompletableFuture<StepResult> executeStep(AgentContext context);

    /**
     * 创建智能体上下文
     * 
     * @param request 用户请求
     * @return 智能体上下文
     */
    private AgentContext createContext(String request) {
        return AgentContext.builder()
            .agentName(name)
            .request(request)
            .memory(memory)
            .build();
    }

    /**
     * 设置智能体状态并发布状态变更事件
     * 
     * @param newState 新状态
     */
    private void setState(AgentState newState) {
        AgentState oldState = this.state;
        this.state = newState;
        
        if (eventPublisher != null) {
            eventPublisher.publishEvent(new AgentStateChangeEvent(this, oldState, newState));
        }
        
        log.debug("Agent [{}] state changed from {} to {}", name, oldState, newState);
    }

    /**
     * 检查智能体是否可以处理指定类型的任务
     * 
     * @param taskType 任务类型
     * @return 是否可以处理
     */
    public boolean canHandle(String taskType) {
        // 默认实现，子类可以重写
        return true;
    }

    /**
     * 清理资源
     */
    public void cleanup() {
        log.info("Agent [{}] cleaning up resources", name);
        // 子类可以重写此方法来清理特定资源
    }
}
